home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / nn.zip / ANSWER.C < prev    next >
C/C++ Source or Header  |  1989-12-31  |  11KB  |  545 lines

  1. #include "config.h"
  2. #include "news.h"
  3. #include "term.h"
  4. #include "keymap.h"
  5.  
  6. extern char *temp_file;
  7.  
  8. export char *default_distribution = NULL;
  9. export char *extra_mail_headers    = NULL;
  10. export char *extra_news_headers    = NULL;
  11. export char *mail_record    = NULL;
  12. export char *news_record    = NULL;
  13. export char *mail_script    = NULL;
  14. export char *news_script    = NULL;
  15.  
  16. export int nn_re_style        = 0;    /* use Re^n: in replies */
  17. export int include_art_id    = 0;
  18.  
  19. #define INCL_MARK_SIZE    10
  20.  
  21. export char included_mark[INCL_MARK_SIZE + 1] = ">";
  22.  
  23.  
  24. static int ed_line;
  25.  
  26.  
  27. answer(ah, command, incl)
  28. article_header *ah;
  29. int command;
  30. int incl;    /* <0: ask, 0: don't include, >0: include article */
  31. {
  32.     register FILE *t, *art;
  33.     char *pgm, *first_action, *record_file;
  34.     int edit_message;
  35.     char *str, *script;
  36.     news_header_buffer nhbuf, dhbuf;
  37.     
  38.     first_action = "edit";
  39.     edit_message = 1;
  40.     
  41.     if (incl < 0) {
  42.     prompt("Include original article? ");
  43.     if ((incl = yes(0)) < 0) return 0;
  44.     }
  45.     
  46.     art = NULL;
  47.     if (ah && ah->a_group) init_group(ah->a_group);
  48.     
  49.     if (incl || command != K_MAIL_OR_FORWARD) {
  50.     int open_modes;
  51.     
  52.     open_modes = FILL_NEWS_HEADER | GET_ALL_FIELDS | SKIP_HEADER;
  53.     if (ah->flag & A_DIGEST) open_modes |= FILL_DIGEST_HEADER;
  54.     
  55.     art = open_news_article(ah, open_modes, nhbuf, dhbuf);
  56.     if (art == NULL) {
  57.         msg("Can't find original article");
  58.         return 0;
  59.     }
  60.     
  61.     if (ah->flag & A_DIGEST) {
  62.         if (digest.dg_from)
  63.         news.ng_path = news.ng_from = digest.dg_from;
  64.         if (digest.dg_subj)
  65.         news.ng_subj = digest.dg_subj;
  66.     }
  67.     } else
  68.     ah = NULL;
  69.     
  70.     /* build header */
  71.     new_temp_file();
  72.     
  73.     if ((t = open_file(temp_file, OPEN_CREATE)) == NULL) {
  74.     msg("Can't create %s", temp_file);
  75.     return 0;
  76.     }
  77.  
  78.     ed_line = 0;
  79.  
  80.  follow_to_poster:
  81.  
  82.     record_file = mail_record;
  83.     script = mail_script;
  84.  
  85.     if (command == K_REPLY) {
  86.     pgm = "reply";
  87.     ah->flag |= A_ST_REPLY;
  88.     
  89.     if (reply_to(t, news.ng_reply) ||
  90.         reply_to(t, news.ng_from) ||
  91.         reply_to(t, news.ng_path)) goto alt0;
  92.     if (to_line(t, news.ng_reply)) goto alt1;
  93.     if (to_line(t, news.ng_from)) goto alt2;
  94.     if (to_line(t, news.ng_path)) goto alt3;
  95.     goto err;
  96.  
  97.      alt0:
  98.     alt_to_line(t, news.ng_reply);
  99.      alt1:
  100.     alt_to_line(t, news.ng_from);
  101.      alt2:
  102.     alt_to_line(t, news.ng_path);
  103.      alt3:
  104.     
  105.     if (news.ng_subj)
  106.         subj_line(t, ah->replies, ah->subject, (char *)NULL);
  107.     else
  108.         subj_line(t, 0, current_group->group_name, "Your Article in");
  109.     
  110.     ng_line(t, 0);
  111.     ref_line(t);
  112.     
  113.     end_header(t, extra_mail_headers);
  114.  
  115.     if (incl) {
  116.         fprintf(t, "In %s you write:\n", current_group->group_name);
  117.         ed_line++;
  118.     }
  119.     }
  120.  
  121.     if (command == K_FOLLOW_UP) {
  122.     if (news.ng_follow && strcmp(news.ng_follow, "poster") == 0) {
  123.         command = K_REPLY;
  124.         msg("Followup by reply to poster");
  125.         goto follow_to_poster;
  126.     }
  127.     
  128.     pgm = "follow";
  129.     record_file = news_record;
  130.     script = news_script;
  131.     ah->flag |= A_ST_FOLLOW;
  132.     
  133.     ng_line(t, 1);
  134.  
  135.     if (news.ng_subj)
  136.         subj_line(t, ah->replies, ah->subject, (char *)NULL);
  137.     else
  138.         if (!subj_line(t, 0, news.ng_from, "Babble from"))
  139.         if (!subj_line(t, 0, news.ng_ident, "Article")) {
  140.             prompt("Subject: ");
  141.             str = get_s(NONE, NONE, NONE, NO_COMPLETION);
  142.             if (str == NULL) goto err;
  143.             subj_line(t, -1, str, (char *)NULL);
  144.         }
  145.  
  146.     if (news.ng_keyw) {
  147.         fprintf(t, "Keywords: %s\n", news.ng_keyw);
  148.         ed_line++;
  149.     }
  150.     
  151.     if (news.ng_dist) {
  152.         fprintf(t, "Distribution: %s\n", news.ng_dist);
  153.         ed_line++;
  154.     }
  155.  
  156.     ref_line(t);
  157.     
  158.     end_header(t, extra_news_headers);
  159.  
  160.     if (incl) {
  161.         if (news.ng_from) {
  162.         if (include_art_id && news.ng_ident)
  163.             fprintf(t, "In %s %s ", 
  164.                 ah->flag & A_DIGEST ? "digest" : "article",
  165.                 news.ng_ident);
  166.         fprintf(t, "%s writes:\n", news.ng_from);
  167.         ed_line++;
  168.         } else
  169.         if (news.ng_ident) {
  170.         fprintf(t, "In %s %s:\n", 
  171.             ah->flag & A_DIGEST ? "digest" : "article",
  172.             news.ng_ident);
  173.         ed_line++;
  174.         }
  175.     }
  176.     }
  177.     
  178.     if (command == K_MAIL_OR_FORWARD) {
  179.     pgm = incl ? "forward" : "mail";
  180.     
  181.      m3_again:
  182.     prompt("To: ");
  183.     str = get_s(user_name(), NONE, NONE, NO_COMPLETION);
  184.     if (str == NULL) goto close_t;
  185.  
  186.     if (*str == NUL) str = user_name();
  187.     if (*str == '?') goto m3_again;
  188.  
  189.     if (strcmp(str, user_name()) == 0)
  190.         record_file = NULL;    /* we will get this anyway,
  191.                    there is so no need to save it */ 
  192.     
  193. /*    if (reply_to(t, str)) {        alt_to_line(t, str);    } else */
  194.     to_line(t, str);
  195.  
  196.     do {
  197.         prompt("Subject: ");
  198.         str = get_s(incl ? ah->subject : NONE, NONE, NONE, NO_COMPLETION);
  199.         if (str == NULL) goto close_t;
  200.         if (*str == NUL && incl) str = ah->subject;
  201.     } while (*str == NUL);
  202.  
  203.     subj_line(t, -1, str, (char *)NULL);
  204.  
  205.     end_header(t, extra_mail_headers);
  206.    
  207.     if (incl) {
  208.         prompt("\1Edit\1 forwarded message? ");
  209.         if ((edit_message = yes(0)) < 0) goto close_t;
  210.         if (!edit_message) {
  211.         first_action = "send";
  212.         fseek(art, ah->hpos, 0);
  213.         }
  214.     }
  215.  
  216.     }
  217.  
  218.     /* empty line terminates header */
  219.     fputc(NL, t);
  220.     ed_line++;
  221.  
  222.     prompt("\1WAIT\1");
  223.     
  224.     if (incl) {
  225.     register c, prevnl = 1;
  226.     
  227.     while ((c = getc(art)) != EOF) {
  228.         if (c == NL) {
  229.         putc(c, t);
  230.         if (ftell(art) >= ah->lpos) break;
  231.         prevnl++;
  232.         continue;
  233.         }
  234.         if (prevnl) {
  235.         if (command != K_MAIL_OR_FORWARD || ftell(art) < ah->fpos)
  236.             fputs(included_mark, t);
  237.         prevnl = 0;
  238.         }
  239.         putc(c, t);
  240.     }
  241.     } else {
  242.     putc(NL, t);
  243.     ed_line++;
  244.     }
  245.     
  246.     fclose(t);
  247.     if (art) fclose(art);
  248.     
  249.     aux_sh(script, pgm, first_action, record_file,
  250.        command == K_FOLLOW_UP ? "Article not posted" : "Mail not sent");
  251.     
  252.     return edit_message;
  253.     
  254.  err:
  255.     msg("Can't build header for %s", 
  256.     command != K_FOLLOW_UP ? "letter" : "article");
  257.  
  258.  close_t:
  259.     fclose(t);
  260.     unlink(temp_file);
  261.     if (art) fclose(art);
  262.     
  263.     return 0;
  264. }
  265.  
  266.  
  267. cancel(ah)
  268. article_header *ah;
  269. {
  270.     news_header_buffer nhbuf;
  271.     FILE *f;
  272.     
  273.     if (ah->a_group) init_group(ah->a_group);
  274.     
  275.     if (ah->flag & A_DIGEST) {
  276.     fputs("\rCancel entire digest ? ", stdout); clrline();
  277.     if (yes(1) > 0) 
  278.         ah->flag &= ~A_DIGEST;
  279.     else {
  280.         msg("Can only cancel entire digests (yet?)");
  281.         return 2;
  282.     }
  283.     } else {
  284.     prompt("Confirm cancel: '%s: %.30s'",
  285.            ah->sender ? ah->sender : "",
  286.            ah->subject ? ah->subject : ""); 
  287.     if (yes(1) <= 0) return 1;
  288.     }
  289.     
  290.     f = open_news_article(ah, FILL_NEWS_HEADER|GET_ALL_FIELDS, nhbuf, (char *)NULL);
  291.     if (f == NULL) {
  292.     msg("Article not found");
  293.     return 2;
  294.     }
  295.     fclose(f);
  296.     
  297.     printf("\rCancelling article %s in group %s",
  298.        news.ng_ident, current_group->group_name);
  299.     clrline();
  300.     
  301.     ed_line = -1;
  302.     
  303.     if (aux_sh((char *)NULL, "cancel", 
  304.            news.ng_ident, current_group->group_name, "Not canceled"))
  305.     return -1;
  306.         
  307.     return 0;
  308. }
  309.  
  310.  
  311. post_menu()
  312. {
  313.     FILE *t;
  314.     char *str, *tail;
  315.     char group_name[FILENAME], subject[FILENAME], 
  316.          distribution[FILENAME], keywords[FILENAME];
  317.     extern group_completion();
  318.     
  319.     group_name[0] = NUL;
  320.     
  321.  again_group:
  322.  
  323.     prompt("\1POST to group\1 ");
  324.     
  325.     str = get_s(current_group ? current_group->group_name : NONE, 
  326.         group_name, NONE, group_completion);
  327.     if (str == NULL || *str == NUL) return 0;
  328.     strcpy(group_name, str);
  329.     
  330.     for (str = group_name; str; str = tail) {
  331.     tail = strchr(str, ',');
  332.     if (tail) *tail = NUL;
  333.     
  334.     if (lookup(str) == NULL) {
  335.         msg("unknown group: %s", str);
  336.         *str = NUL;
  337.         goto again_group;
  338.     }
  339.  
  340.     if (tail) *tail++ = ',';
  341.     }
  342.  
  343.     prompt("Subject: ");
  344.     str = get_s(NONE, NONE, NONE, NO_COMPLETION);
  345.     if (str == NULL || *str == NUL) return 0;
  346.     strcpy(subject, str);
  347.     
  348.     prompt("Keywords: ");
  349.     str = get_s(NONE, NONE, NONE, NO_COMPLETION);
  350.     if (str == NULL) return 0;
  351.     strcpy(keywords, str);
  352.     
  353.     if (default_distribution != NULL)
  354.     strcpy(distribution, default_distribution);
  355.     else {
  356.     strcpy(distribution, group_name);
  357.     if (str = strchr(distribution, '.')) *str = NUL;
  358.     }
  359.     
  360.     prompt("\1Distribution\1 (default '%s') ", distribution);
  361.     str = get_s(NONE, NONE, NONE, NO_COMPLETION);
  362.     if (str == NULL) return 0;
  363.     if (*str) strcpy(distribution, str);
  364.  
  365.     new_temp_file();
  366.     if ((t = open_file(temp_file, OPEN_CREATE)) == NULL) {
  367.     msg("Can't create %s", temp_file);
  368.     return 0;
  369.     }
  370.  
  371.     prompt("\1WAIT\1");
  372.     
  373.     ed_line = 5;
  374.     fprintf(t, "Newsgroups: %s\n", group_name);
  375.     fprintf(t, "Distribution: %s\n", distribution);
  376.     fprintf(t, "Subject: %s\n", subject);
  377.     if (*keywords) {
  378.     fprintf(t, "Keywords: %s\n", keywords);
  379.     ed_line++;
  380.     }
  381.  
  382.     end_header(t, extra_news_headers);
  383.     fputc(NL, t);
  384.  
  385.     fclose(t);
  386.     
  387.     aux_sh(news_script, "post", "edit", news_record, "Article not posted");
  388.     
  389.     return 1;
  390. }
  391.  
  392. static subj_line(t, re, subj, prefix)
  393. FILE *t;
  394. int re;
  395. char *subj, *prefix;
  396. {
  397.     if (subj == NULL) return 0;
  398.     
  399.     fputs("Subject: ", t);
  400.  
  401.     if (re == 0 || !nn_re_style) 
  402.     fputs("Re: ", t);
  403.     else if (re > 0)
  404.     fprintf(t, "Re^%d: ", re + 1);
  405.  
  406.     if (prefix) {
  407.     fputs(prefix, t);
  408.     fputc(' ', t);
  409.     }
  410.     
  411.     fputs(subj, t);
  412.     fputc(NL, t);
  413.  
  414.     ed_line++;
  415.     return 1;
  416. }
  417.  
  418.  
  419. static ng_line(t, use_follow)
  420. FILE *t;
  421. int use_follow;
  422. {    
  423.     fprintf(t, "Newsgroups: %s\n", 
  424.         use_follow && news.ng_follow ? news.ng_follow : news.ng_groups);
  425.     ed_line++;
  426. }
  427.  
  428. static ref_line(t)
  429. FILE *t;
  430. {
  431.     if (news.ng_ref == NULL && news.ng_ident == NULL) return;
  432.     
  433.     fputs("References:", t);
  434.     if (news.ng_ref) fprintf(t, " %s", news.ng_ref);
  435.     if (news.ng_ident) fprintf(t, " %s", news.ng_ident);
  436.     putc(NL, t);
  437.     ed_line++;
  438. }
  439.  
  440.  
  441. static to_line(t, to)
  442. FILE *t;
  443. char *to;
  444. {    
  445.     if (to == NULL) return 0;
  446.  
  447.     fprintf(t, "To: %s\n", to);
  448.     ed_line++;
  449.     return 1;
  450. }
  451.  
  452. static alt_to_line(t, to)
  453. FILE *t;
  454. char *to;
  455. {    
  456.     if (to == NULL) return;
  457.  
  458.     fprintf(t, "Orig-To: %s\n", to);
  459.     ed_line++;
  460. }
  461.  
  462. static end_header(t, extra_headers)
  463. FILE *t;
  464. register char *extra_headers;
  465. {
  466.     if (extra_headers != NULL && *extra_headers != NUL) {
  467.     while (*extra_headers != NUL) {
  468.         if (*extra_headers == ';') {
  469.         if (*++extra_headers == NUL) break;
  470.         fputc(NL, t);
  471.         ed_line++;
  472.         } else
  473.         fputc(*extra_headers++, t);
  474.     }
  475.     fputc(NL, t);
  476.     ed_line++;
  477.     }
  478.     
  479.     fputc(NL, t);
  480.     ed_line++;
  481. }
  482.  
  483.  
  484. static reply_to(t, address)
  485. FILE *t;
  486. char *address;
  487. {
  488.     char route[512];
  489.     
  490.     if (address == NULL) return 0;
  491.  
  492.     if (reroute(route, address)) {
  493.     to_line(t, route);
  494.     return 1;
  495.     }
  496.     return 0;
  497. }
  498.         
  499.  
  500. /*
  501.  * invoke aux shell script with suitable arguments
  502.  *
  503.  * WARNING: record may be NULL, soit must be the last argument!!
  504.  */
  505.  
  506. static aux_sh(script, prog, action, record, not_sent)
  507. char *script, *prog, *action, *record, *not_sent;
  508. {
  509.     char *args[8];
  510.     char number[10];
  511.     register char **ap = args;
  512.     time_t start_t;
  513.     
  514.     *ap++ = "nnaux";
  515.     *ap++ = script != NULL ? script : relative(lib_directory, "aux");
  516.     *ap++ = prog;
  517.  
  518.     if (ed_line >= 0) {    /* not cancel */
  519.     sprintf(number, "%d", ed_line);
  520.     *ap++ = temp_file;
  521.     *ap++ = number;
  522.     }
  523.     
  524.     *ap++ = action;    /* article id for cancel */
  525.     *ap++ = record;    /* group name for cancel */
  526.  
  527.     *ap++ = NULL;
  528.  
  529. #ifdef STATISTICS    
  530.     time(&start_t);
  531. #endif    
  532.     if (execute(SHELL, args)) {
  533.     prompt_line = -1;
  534.     prompt("\1%s\1", not_sent);
  535.     sleep(1);
  536.     return 1;
  537.     }
  538.     
  539. #ifdef STATISTICS    
  540.     tick_usage((time_t *)NULL, &start_t);
  541. #endif
  542.     
  543.     return 0;
  544. }
  545.